<?php

namespace app\ask\controller;

use think\Controller;

// 引入FastAdmin自带的一个邮箱发送类
use app\common\library\Email;

class Business extends Controller
{
    protected $BusinessModel;
    protected $PayModel;
    protected $PostModel;
    protected $CollectModel;
    protected $PostCommentModel;
    protected $FriendModel;
    protected $RecordModel;

    public function __construct()
    {
        parent::__construct();

        $this->BusinessModel = model('Business.Business');
        $this->PayModel = model('pay.Pay');
        $this->PostModel = model('post.Post');
        $this->CollectModel = model('post.Collect');
        $this->PostCommentModel = model('post.Comment');
        $this->FriendModel = model('Friend');
        $this->RecordModel = model('Business.Record');
    }
    public function login()
    {
        if ($this->request->isPost()) {
            $code = $this->request->param('code', '', 'trim');

            if (empty($code)) {
                $this->error('临时凭证获取失败');
                exit;
            }

            //发送请求给微信端
            $wxauth = $this->code2Session($code);

            $openid = isset($wxauth['openid']) ? trim($wxauth['openid']) : '';

            if (empty($openid)) {
                $this->error('授权失败');
                exit;
            }

            // 根据openid查找是否存在用户
            $business = $this->BusinessModel->where(['openid' => $openid])->find();

            if ($business) {
                // 删除敏感数据
                unset($business['salt']);
                unset($business['password']);

                //授权成功
                $this->success('授权登录成功', null, $business);
                exit;
            } else {
                $this->success('授权成功，请绑定账号', "/pages/business/login", ['action' => 'bind', 'openid' => $openid]);
                exit;
            }
        }
    }

    // 绑定
    public function bind()
    {
        if ($this->request->isPost()) {
            $openid = $this->request->param('openid', '', 'trim');
            $password = $this->request->param('password', '', 'trim');
            $mobile = $this->request->param('mobile', '', 'trim');

            $business = $this->BusinessModel->where(['mobile' => $mobile])->find();

            //如果找得到就说明绑定过， 如果找不到就说明账号不存在，就注册插入
            if ($business) {
                //更新语句
                if (!empty($business['openid'])) {
                    $this->error('该用户已绑定，无法重复绑定');
                    exit;
                }

                $data = [
                    'id' => $business['id'],
                    'openid' => $openid
                ];

                //更新语句
                $result = $this->BusinessModel->isUpdate(true)->save($data);

                if ($result === FALSE) {
                    $this->error('绑定账号失败');
                    exit;
                } else {
                    $business['openid'] = $openid;
                    // 删除敏感数据
                    unset($business['salt']);
                    unset($business['password']);
                    $this->success('绑定账号成功', null, $business);
                    exit;
                }
            } else {
                //数据插入
                if (empty($password)) {
                    $this->error('密码不能为空');
                    exit;
                }

                //生成一个密码盐
                $salt = randstr();

                //加密密码
                $password = md5($password . $salt);

                //组装数据
                $data = [
                    'openid' => $openid,
                    'mobile' => $mobile,
                    'nickname' => $mobile,
                    'password' => $password,
                    'salt' => $salt,
                    'gender' => '0', //性别
                    'deal' => '0', //成交状态
                    'money' => '0', //余额
                    'auth' => '0', //实名认证
                ];

                //查询出云课堂的渠道来源的ID信息 数据库查询
                $data['sourceid'] = model('common/Business/Source')->where(['name' => ['LIKE', "%问答社区%"]])->value('id');

                //执行插入 返回自增的条数
                $result = $this->BusinessModel->validate('common/Business/Business')->save($data);

                if ($result === FALSE) {
                    //失败
                    $this->error($this->BusinessModel->getError());
                    exit;
                } else {
                    //查询出当前插入的数据记录
                    $business = $this->BusinessModel->find($this->BusinessModel->id);

                    //注册
                    $this->success('注册成功', null, $business);
                    exit;
                }
            }
        }
    }

    // 解除绑定
    public function unbind()
    {
        if ($this->request->isPost()) {
            $busid = $this->request->param('busid', 0, 'trim');

            $business = $this->BusinessModel->find($busid);

            if (!$business) {
                $this->error('未找到该用户');
                exit;
            }

            if ($business['openid'] === null) {
                $this->error('您未绑定');
                exit;
            }

            $data = [
                'id' => $busid,
                'openid' => null
            ];

            $result = $this->BusinessModel->isUpdate(true)->save($data);

            if ($result === false) {
                $this->error('解除失败');
                exit;
            } else {
                $this->success('解除成功，请重新登录');
                exit;
            }
        }
    }

    public function web()
    {
        if ($this->request->isPost()) {
            $password = $this->request->param('password', '', 'trim');
            $mobile = $this->request->param('mobile', '', 'trim');

            $business = $this->BusinessModel->where(['mobile' => $mobile])->find();

            // 登录
            if ($business) {
                //验证密码是否正确
                $salt = $business['salt'];
                $password = md5($password . $salt);

                if ($password != $business['password']) {
                    $this->error('密码错误');
                    exit;
                } else {
                    unset($business['salt']);
                    unset($business['password']);
                    $this->success('登录成功', null, $business);
                    exit;
                }
            } else {
                // 注册
                if (empty($password)) {
                    $this->error('密码不能为空');
                    exit;
                }

                //生成一个密码盐
                $salt = randstr();

                //加密密码
                $password = md5($password . $salt);

                //组装数据
                $data = [
                    'mobile' => $mobile,
                    'nickname' => $mobile,
                    'password' => $password,
                    'salt' => $salt,
                    'gender' => '0', //性别
                    'deal' => '0', //成交状态
                    'money' => '0', //余额
                    'auth' => '0', //实名认证
                ];

                //查询出云课堂的渠道来源的ID信息 数据库查询
                $data['sourceid'] = model('common/Business/Source')->where(['name' => ['LIKE', "%问答社区%"]])->value('id');

                //执行插入 返回自增的条数
                $result = $this->BusinessModel->validate('common/Business/Business')->save($data);

                if ($result === FALSE) {
                    //失败
                    $this->error($this->BusinessModel->getError());
                    exit;
                } else {
                    //查询出当前插入的数据记录
                    $business = $this->BusinessModel->find($this->BusinessModel->id);

                    unset($business['salt']);
                    unset($business['password']);

                    //注册
                    $this->success('注册成功', null, $business);
                    exit;
                }
            }
        }
    }

    // 调用微信官方获取用户信息
    public function code2Session($code)
    {
        if ($code) {

            // 改成自己的小程序 appid
            $appid = "wx27782cab82a5eca3";

            // 改成自己的小程序 appSecret
            $appSecret = "c55f03ba4f8ca265dd237776e3235d4f";

            // 微信官方提供的接口，获取唯一的opendid
            $url = "https://api.weixin.qq.com/sns/jscode2session?appid=$appid&secret=$appSecret&js_code=$code&grant_type=authorization_code";

            $result = $this->https_request($url);

            //获取结果 将json转化为数组
            $resultArr = json_decode($result, true);

            return $resultArr;
        }
        return false;
    }
    // http请求 利用php curl扩展去发送get 或者 post请求 服务器上面一定要开启 php curl 扩展
    // https://www.php.net/manual/zh/book.curl.php
    protected function https_request($url, $data = null)
    {
        if (function_exists('curl_init')) {
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
            curl_setopt($curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
            if (!empty($data)) {
                curl_setopt($curl, CURLOPT_POST, 1);
                curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
            }
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            // 发送会话，返回结果
            $output = curl_exec($curl);
            curl_close($curl);
            return $output;
        } else {
            return false;
        }
    }

    // 修改个人基本资料
    public function profile()
    {
        $id = $this->request->param('id', 0, 'trim');
        $nickname = $this->request->param('nickname', '', 'trim');
        $mobile = $this->request->param('mobile', '', 'trim');
        $email = $this->request->param('email', '', 'trim');
        $gender = $this->request->param('gender', '0', 'trim');
        $code = $this->request->param('code', '', 'trim');
        $password = $this->request->param('password', '', 'trim');

        $business = $this->BusinessModel->find($id);

        if (!$business) {
            $this->error('用户不存在');
            exit;
        }

        $data = [
            'id'       => $business['id'],
            'nickname' => $nickname,
            'mobile'   => $mobile,
            'gender'   => $gender,
        ];

        // 用户输入新密码，就重新生成密码盐和密码
        if (!empty($password)) {
            //重新生成一份密码盐
            $salt = randstr();

            $data['salt'] = $salt;
            $data['password'] = md5($password . $salt);
        }

        // 修改了邮箱就取消认证状态
        if ($email != $business['email']) {
            $data['email'] = $email;
            $data['auth'] = '0';
        }

        // 修改地区
        if (!empty($code)) {
            //查询省市区的地区码出来
            $parent = model('Region')->where(['code' => $code])->value('parentpath');

            if (!empty($parent)) {
                $arr = explode(',', $parent);
                $data['province'] = isset($arr[0]) ? $arr[0] : null;
                $data['city'] = isset($arr[1]) ? $arr[1] : null;
                $data['district'] = isset($arr[2]) ? $arr[2] : null;
            }
        }

        // 修改头像
        if (isset($_FILES['avatar']) && $_FILES['avatar']['error'] == 0) {
            $result = upload_image('avatar');

            if (!$result['success']) {
                $this->error($result['msg']);
                exit;
            }

            $data['avatar'] = $result['data'];
        }

        $result = $this->BusinessModel->validate('common/Business/Business.profile')->isUpdate(true)->save($data);

        // 写入数据库失败
        if ($result = false) {
            $this->error($this->BusinessModel->getError());
            exit;
        }

        // 判断是否有旧图片，有则删除
        if (isset($data['avatar'])) {
            $old_avatar = '.' . $business['avatar'];
            is_file($old_avatar) && @unlink($old_avatar);
        }

        $business = $this->BusinessModel->find($id);

        // 删除敏感数据
        unset($business['password']);
        unset($business['salt']);

        $this->success('更新资料成功', null, $business);
        exit;
    }

    // 个人主页信息
    public function center()
    {
        $busid = $this->request->param('busid', 0, 'trim');

        // 自己的用户id
        $selfbusid = $this->request->param('selfbusid', 0, 'trim');

        $business = $this->BusinessModel->find($busid);

        if (!$business) {
            $this->error('用户不存在');
            exit;
        }

        $data = [
            'post' => 0,
            'collect' => 0,
            'comment' => 0,
            'friend' => false,
            'business' => filter_property($business, ['id', 'avatar_text', 'nickname'])
        ];

        $where = ['busid' => $busid];

        $postCount = $this->PostModel->where($where)->count();
        $data['post'] = $postCount ? $postCount : 0;

        $collecCount = $this->CollectModel->where($where)->count();
        $data['collect'] = $collecCount ? $collecCount : 0;

        $commentCount = $this->PostCommentModel->where($where)->count();
        $data['comment'] = $commentCount ? $commentCount : 0;

        if ($selfbusid) {
            $friend = $this->FriendModel->where(['busid' => $selfbusid, 'fansid' => $busid])->find();

            if ($friend) {
                $data['friend'] = true;
            }
        }

        $this->success('获取成功', null, $data);
        exit;
    }

    // 获取钱包信息
    public function wallet()
    {
        $busid = $this->request->param('busid', 0, 'trim');

        $business = $this->BusinessModel->find($busid);

        if (!$business) {
            $this->error('用户不存在');
            exit;
        }

        $result = [
            'money' => $business['money'],
        ];

        $this->success('获取成功', null, $result);
    }

    // 充值
    public function pay()
    {
        if ($this->request->isPost()) {
            $busid = $this->request->param('busid', 0, 'trim');
            $money = $this->request->param('money', 1, 'trim');
            $type = $this->request->param('type', 'wx', 'trim');


            // 判断用户是否存在
            $business = $this->BusinessModel->find($busid);

            if (!$business) {
                $this->error('用户不存在');
                exit;
            }

            if ($money <= 0) {
                $this->error('充值金额不能小于0元');
                exit;
            }

            // 发送一个接口请求出去
            $host = config('site.cdnurl');
            $host = trim($host, '/');

            // 完整的请求接口地址
            $api = $host . "/pay/index/create";

            // 订单支付完成后跳转的界面
            $reurl = "http://shop.xdlayman.cn/#/business/pay";

            $callbackurl = $host . "/ask/business/callback";

            // 携带一个自定义的参数过去 转换为json类型
            $third = json_encode(['busid' => $busid]);

            // 微信收款码
            $wxcode = config('site.wxcode');
            $wxcode = $host . $wxcode;

            // 支付宝收款码
            $zfbcode = config('site.zfbcode');
            $zfbcode = $host . $zfbcode;

            // 充值信息
            $PayData = [
                'name' => '余额充值',
                'third' => $third,
                'originalprice' => $money,
                //微信支付
                // 'paytype' => 0,
                // 'paypage' => 1,
                //支付宝支付
                // 'paytype' => 1,
                // 'paypage' => 2,
                'paypage' => 0,
                'wxcode' => $wxcode,
                'zfbcode' => $zfbcode,
                'reurl' => $reurl,
                'callbackurl' => $callbackurl,
            ];

            // 要看是哪一种支付方式
            if ($type == 'wx') {
                //微信
                $PayData['paytype'] = 0;
            } else {
                //支付宝
                $PayData['paytype'] = 1;
            }

            // 发起请求
            $result = httpRequest($api, $PayData);

            // 有错误
            if (isset($result['code']) && $result['code'] == 0) {
                $this->error($result['msg']);
                exit;
            }

            //将json转换为php数组
            $result = json_decode($result, true);

            $this->success('生成付款码', null, $result['data']);
            exit;
        }
    }
    // 查询支付订单订单是否成功
    public function query()
    {
        if ($this->request->isPost()) {
            $busid = $this->request->param('busid', 0, 'trim');
            $payid = $this->request->param('payid', '', 'trim');

            // 判断用户是否存在
            $business = $this->BusinessModel->find($busid);

            if (!$business) {
                $this->error('用户不存在');
                exit;
            }

            if (empty($payid)) {
                $this->error('支付记录不存在');
                exit;
            }

            //发送一个接口请求出去
            $host = config('site.cdnurl');
            $host = trim($host, '/');

            // 完整的请求接口地址
            $api = $host . "/pay/index/status";

            //发起请求
            $result = httpRequest($api, ['payid' => $payid]);

            // 将json转换为php数组
            $result = json_decode($result, true);

            if (isset($result['code']) && $result['code'] == 0) {
                $this->error($result['msg']);
                exit;
            } else {
                $status = isset($result['data']['status']) ? $result['data']['status'] : 0;
                $this->success('查询充值状态', null, ['status' => $status]);
                exit;
            }
        }
    }
    //充值回调
    public function callback()
    {
        // 判断是否有post请求过来
        if ($this->request->isPost()) {
            // 获取到所有的数据
            $params = $this->request->param();

            // 充值的金额
            $price = isset($params['price']) ? $params['price'] : 0;
            $price = floatval($price);

            // 第三方参数(可多参数)
            $third = isset($params['third']) ? $params['third'] : '';

            // json字符串转换数组
            $third = json_decode($third, true);

            // 从数组获取充值的用户id
            $busid = isset($third['busid']) ? $third['busid'] : 0;

            // 支付方式
            $paytype = isset($params['paytype']) ? $params['paytype'] : 0;

            // 支付订单id
            $payid = isset($params['id']) ? $params['id'] : 0;

            $pay = $this->PayModel->find($payid);

            if (!$pay) {
                return json(['code' => 0, 'msg' => '支付订单不存在', 'data' => null]);
            }

            $payment = '';

            switch ($paytype) {
                case 0:
                    $payment = '微信支付';
                    break;
                case 1:
                    $payment = '支付宝支付';
                    break;
            }

            // 判断充值金额
            if ($price <= 0) {
                return json(['code' => 0, 'msg' => '充值金额为0', 'data' => null]);
            }

            $business = $this->BusinessModel->find($busid);

            if (!$business) {
                return json(['code' => 0, 'msg' => '充值用户不存在', 'data' => null]);
            }

            // 开启事务
            $this->BusinessModel->startTrans();
            $this->RecordModel->startTrans();

            // 转成浮点类型
            $money = floatval($business['money']);

            // 余额 + 充值的金额
            $updateMoney = bcadd($money, $price, 2);

            // 封装用户更新的数据
            $BusinessData = [
                'id' => $business['id'],
                'money' => $updateMoney
            ];

            // 自定义验证器
            $validate = [
                [
                    'money' => ['number', '>=:0'],
                ],
                [
                    'money.number' => '余额必须是数字类型',
                    'money.>=' => '余额必须大于等于0元'
                ]
            ];

            // 更新用户余额
            $BusinessStatus = $this->BusinessModel->validate(...$validate)->isUpdate(true)->save($BusinessData);

            if ($BusinessStatus === false) {
                return json(['code' => 0, 'msg' => $this->BusinessModel->getError(), 'data' => null]);
            }

            // 封装插入消费记录的数据
            $RecordData = [
                'total' => $price,
                'content' => "{$payment}充值了 $price 元",
                'busid' => $business['id']
            ];

            // 插入消费记录
            $RecordStatus = $this->RecordModel->validate('common/Business/Record')->save($RecordData);

            if ($RecordStatus === false) {
                $this->BusinessModel->rollback();
                return json(['code' => 0, 'msg' => $this->RecordModel->getError(), 'data' => null]);
            }

            if ($BusinessStatus === false || $RecordStatus === false) {
                $this->BusinessModel->rollback();
                $this->RecordModel->rollback();
                return json(['code' => 0, 'msg' => '充值失败', 'data' => null]);
            } else {
                $this->BusinessModel->commit();
                $this->RecordModel->commit();

                // 订单号：\r\n
                // 金额:50元
                // 支付方式：
                // 时间，
                return json(['code' => 1, 'msg' => '充值成功', 'data' => null]);
            }
        }
    }
    // 邮箱验证
    public function email()
    {
        if ($this->request->isPost()) {
            $id = $this->request->param('id', '', 'trim');
            $action = $this->request->param('action', '', 'trim');

            $EmsModel = model('common/Ems');

            $business = $this->BusinessModel->where(['id' => $id])->find();

            if (empty($business)) {
                $this->error('未知用户');
                exit;
            }

            //获取用户信息
            $email = empty($business['email']) ? '' : trim($business['email']);

            if (empty($email)) {
                $this->error('邮箱地址为空');
                exit;
            }

            if ($action == "send") {
                // 生成验证码
                $code = randstr(6);
                // 开始事务
                $EmsModel->startTrans();
                // 删除之前的验证码记录
                $EmsModel->where(['email' => $email])->delete();
                // 组装数据
                $data = [
                    'event' => 'auth',
                    'email' => $email,
                    'code' => $code,
                    'times' => 0,
                ];
                // 插入数据
                $result = $EmsModel->save($data);

                if ($result === false) {
                    $this->error('邮件发送失败');
                    exit;
                }

                // 实例化邮箱验证类
                $PhpMailer = new Email;

                $name = config('site.name');
                $subject = "【{$name}】邮箱验证";
                $message = "<div>您的邮箱验证码为：<b>$code</b></div>";

                $result = $PhpMailer
                    ->to($email)
                    ->subject($subject)
                    ->message($message)
                    ->send();

                if ($result) {
                    // 提交事务
                    $EmsModel->commit();
                    $this->success('验证码发送成功，请注意查收');
                    exit;
                } else {
                    // 回滚事务
                    $EmsModel->rollback();
                    $this->error($PhpMailer->getError());
                    exit;
                }
            } else {
                // 获取验证码
                $code = $this->request->param('code', '', 'trim');

                if (empty($code)) {
                    $this->error('验证码不能为空');
                    exit;
                }

                $EmsModel->startTrans();
                $this->BusinessModel->startTrans();

                $where = ['email' => $email, 'code' => $code];
                // 查询验证码
                $check = $EmsModel->where($where)->find();

                if (!$check) {
                    $this->error('验证码错误');
                    exit;
                }
                // 组装数据
                $data = [
                    'id'   => $id,
                    'auth' => '1',
                ];

                // 更新认证状态
                $busResult = $this->BusinessModel->isUpdate(true)->save($data);

                if ($busResult === false) {
                    $this->error('更新认证状态失败');
                }

                // 删除验证码
                $EmsResult = $EmsModel->where($where)->delete();

                if ($EmsResult === false) {
                    $this->BusinessModel->rollback();
                    $this->error('验证码记录删除失败');
                    exit;
                }

                if ($busResult === false || $EmsResult === false) {
                    $EmsModel->rollback();
                    $this->BusinessModel->rollback();
                    $this->error('验证失败');
                    exit;
                } else {
                    $EmsModel->commit();
                    $this->BusinessModel->commit();
                    $this->success('验证成功');
                    exit;
                }
            }
        }
    }
}
